"""
ConnLLM重试策略
提供API调用失败时的重试策略
兼容层 - 使用新的函数式实现
"""
import logging
import warnings
from typing import Type, Optional, List, Tuple, Dict, Any, Callable

from ..core.exceptions import (
	LLMException, RateLimitError, ConnectionError, TimeoutError,
	ServerError, QuotaExceededError, AuthenticationError
)

# 设置日志
logger = logging.getLogger("connllm.retry")

# 发出弃用警告
warnings.warn(
	"connllm.utils.retry模块已弃用，请使用connllm.utils.retry.backoff模块", 
	DeprecationWarning, stacklevel=2
)

# 导入新实现
try:
	from .retry.strategies import RetryConfig
	from .retry.backoff import retry_with_backoff, get_retry_delay, should_retry
	
	# 向后兼容的类定义
	class RetryStrategy:
		"""
		重试策略基类（已弃用）
		为兼容性而保留，请使用新的函数式API
		"""
		
		def __init__(self, max_retries: int = 3):
			"""
			初始化重试策略
			
			Args:
				max_retries: 最大重试次数
			"""
			self.max_retries = max(1, max_retries)
			self._config = RetryConfig(max_retries=self.max_retries)
			
		def should_retry(self, attempt: int, error: Exception) -> bool:
			"""
			判断是否应该重试
			
			Args:
				attempt: 当前尝试次数(从0开始)
				error: 发生的错误
				
			Returns:
				是否应该重试
			"""
			return should_retry(attempt, error, self._config)
			
		def get_retry_delay(self, attempt: int, error: Exception) -> float:
			"""
			获取重试延迟时间
			
			Args:
				attempt: 当前尝试次数(从0开始)
				error: 发生的错误
				
			Returns:
				重试延迟时间(秒)
			"""
			return get_retry_delay(attempt, error, self._config)


	class ExponentialBackoffStrategy(RetryStrategy):
		"""
		指数退避重试策略（已弃用）
		为兼容性而保留，请使用新的函数式API
		"""
		
		def __init__(self, max_retries: int = 3, base_delay: float = 1.0, 
					max_delay: float = 60.0, jitter: bool = True):
			"""
			初始化指数退避重试策略
			
			Args:
				max_retries: 最大重试次数
				base_delay: 基础延迟时间(秒)
				max_delay: 最大延迟时间(秒)
				jitter: 是否添加随机抖动
			"""
			super().__init__(max_retries)
			self._config = RetryConfig(
				max_retries=max_retries,
				base_delay=base_delay,
				max_delay=max_delay,
				jitter=jitter
			)


	class RateLimitErrorStrategy(ExponentialBackoffStrategy):
		"""速率限制错误的重试策略（已弃用）"""
		
		def __init__(self, max_retries: int = 5, base_delay: float = 2.0, 
					max_delay: float = 120.0):
			"""
			初始化速率限制错误重试策略
			
			Args:
				max_retries: 最大重试次数(比一般错误多)
				base_delay: 基础延迟时间(秒)(比一般错误长)
				max_delay: 最大延迟时间(秒)
			"""
			super().__init__(max_retries, base_delay, max_delay)


	class ServerErrorStrategy(ExponentialBackoffStrategy):
		"""服务器错误的重试策略（已弃用）"""
		
		def __init__(self, max_retries: int = 4, base_delay: float = 1.5, 
					max_delay: float = 60.0):
			"""
			初始化服务器错误重试策略
			
			Args:
				max_retries: 最大重试次数
				base_delay: 基础延迟时间(秒)
				max_delay: 最大延迟时间(秒)
			"""
			super().__init__(max_retries, base_delay, max_delay)


	class ConnectionErrorStrategy(ExponentialBackoffStrategy):
		"""连接错误的重试策略（已弃用）"""
		
		def __init__(self, max_retries: int = 3, base_delay: float = 1.0, 
					max_delay: float = 30.0):
			"""
			初始化连接错误重试策略
			
			Args:
				max_retries: 最大重试次数
				base_delay: 基础延迟时间(秒)
				max_delay: 最大延迟时间(秒)
			"""
			super().__init__(max_retries, base_delay, max_delay)


	# 不应该重试的错误类型
	NO_RETRY_ERRORS = (
		AuthenticationError,    # 认证错误不太可能通过重试解决
		QuotaExceededError,     # 配额超限需要充值或等待重置
		ValueError,             # 值错误通常表示代码问题
		TypeError               # 类型错误通常表示代码问题
	)


	# 错误类型到重试策略的映射
	ERROR_STRATEGIES = {
		RateLimitError: RateLimitErrorStrategy,
		ServerError: ServerErrorStrategy,
		ConnectionError: ConnectionErrorStrategy,
		TimeoutError: ConnectionErrorStrategy  # 超时错误使用连接错误策略
	}


	# 提供商特定的默认重试策略
	PROVIDER_STRATEGIES = {
		"anthropic": ExponentialBackoffStrategy(
			max_retries=3, base_delay=1.5, max_delay=30.0
		),
		"openai": ExponentialBackoffStrategy(
			max_retries=3, base_delay=1.0, max_delay=30.0
		),
		"openrouter": ExponentialBackoffStrategy(
			max_retries=3, base_delay=2.0, max_delay=45.0
		),
		"moonshot": ExponentialBackoffStrategy(
			max_retries=3, base_delay=1.0, max_delay=30.0
		),
		"default": ExponentialBackoffStrategy(
			max_retries=3, base_delay=1.0, max_delay=30.0
		)
	}


	def create_retry_strategy(provider_type: str, error_type: Optional[Type[Exception]] = None) -> RetryStrategy:
		"""
		创建适用于特定提供商和错误类型的重试策略（已弃用）
		为兼容性而保留，请使用retry_with_backoff函数
		
		Args:
			provider_type: 提供商类型
			error_type: 错误类型，如果为None则使用默认策略
			
		Returns:
			重试策略实例
		"""
		warnings.warn(
			"create_retry_strategy函数已弃用，请使用retry_with_backoff函数",
			DeprecationWarning, stacklevel=2
		)
		
		# 如果错误类型不应该重试，返回不重试的策略
		if error_type and issubclass(error_type, NO_RETRY_ERRORS):
			return RetryStrategy(max_retries=0)  # 最大重试次数为0，表示不重试
			
		# 如果有错误类型特定的策略，使用该策略
		if error_type and error_type in ERROR_STRATEGIES:
			return ERROR_STRATEGIES[error_type]()
			
		# 否则使用提供商特定的策略
		return PROVIDER_STRATEGIES.get(provider_type, PROVIDER_STRATEGIES["default"])

except ImportError:
	# 如果新实现不可用，回退到旧实现
	logger.warning("无法导入新的重试模块，使用旧实现")
	
	# 定义与旧版本相同的类和函数
	class RetryStrategy:
		"""
		重试策略基类
		定义重试行为的基本接口
		"""
		
		def __init__(self, max_retries: int = 3):
			"""
			初始化重试策略
			
			Args:
				max_retries: 最大重试次数
			"""
			self.max_retries = max(1, max_retries)
			
		def should_retry(self, attempt: int, error: Exception) -> bool:
			"""
			判断是否应该重试
			
			Args:
				attempt: 当前尝试次数(从0开始)
				error: 发生的错误
				
			Returns:
				是否应该重试
			"""
			# 超过最大重试次数，不再重试
			if attempt >= self.max_retries:
				return False
				
			# 基本策略：总是重试
			return True
			
		def get_retry_delay(self, attempt: int, error: Exception) -> float:
			"""
			获取重试延迟时间
			
			Args:
				attempt: 当前尝试次数(从0开始)
				error: 发生的错误
				
			Returns:
				重试延迟时间(秒)
			"""
			# 基本策略：固定延迟1秒
			return 1.0
			
	# 导入和实现与上面相同的类和函数...
	# 这里省略了重复的代码，实际情况应当复制完整的旧实现
